package com.swim.pay.service.Impl;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeQueryModel;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.beust.jcommander.internal.Maps;
import com.swim.common.utils.ConstantUtil;
import com.swim.common.utils.SmsUtil;
import com.swim.natatoriumgoods.entity.NatatoriumGoods;
import com.swim.natatoriumgoods.service.NatatoriumGoodsService;
import com.swim.natatoriumorder.entity.NatatoriumOrder;
import com.swim.natatoriumorder.service.NatatoriumOrderService;
import com.swim.pay.bean.AliPayBean;
import com.swim.pay.service.AliPayService;

import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;

/**
 * 支付宝支付接口实现类
 * @Author sampson
 * @Description AliPayServiceImpl
 * @Date 21-8-16 下午3:20
 * @Version 1.0
 */
@Slf4j
@Service
public class AliPayServiceImpl implements AliPayService {

    private Logger logger = LoggerFactory.getLogger(AliPayServiceImpl.class);
    @Autowired
    private NatatoriumOrderService natatoriumOrderService;
    @Autowired
    private NatatoriumGoodsService natatoriumGoodsService;
    @Override
    public String aliPayH5Order(AliPayBean aliPayBean) throws AlipayApiException {

        //支付成功同步回调地址
        String returnUrl = String.format(ConstantUtil.ali_return_url, aliPayBean.getOutTradeNo());

        AlipayClient alipayClient = new DefaultAlipayClient(ConstantUtil.gatewayUrl,
                ConstantUtil.ali_app_id,ConstantUtil.alipay_private_key,ConstantUtil.format,ConstantUtil.charset,
                ConstantUtil.alipay_public_key,ConstantUtil.sign_type);

        AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();

        AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
        model.setOutTradeNo(aliPayBean.getOutTradeNo());
        model.setSubject(aliPayBean.getSubject());
        model.setTotalAmount(aliPayBean.getTotalFee().toString());
        model.setBody(aliPayBean.getDesc());
        model.setTimeoutExpress("2m");
        model.setProductCode("QUICK_WAP_PAY");
        request.setBizModel(model);
        request.setNotifyUrl(ConstantUtil.ali_notify_url);
        request.setReturnUrl(returnUrl);
        String form = alipayClient.pageExecute(request).getBody();
        return form;
    }

    @Override
    public String aliPayOrderQuery(String outTradeNo) throws AlipayApiException {
        AlipayClient alipayClient = new DefaultAlipayClient(ConstantUtil.gatewayUrl,
                ConstantUtil.ali_app_id,ConstantUtil.alipay_private_key,ConstantUtil.format,ConstantUtil.charset,
                ConstantUtil.alipay_public_key,ConstantUtil.sign_type);
        AlipayTradeQueryRequest alipayTradeQueryRequest = new AlipayTradeQueryRequest();

        AlipayTradeQueryModel model=new AlipayTradeQueryModel();
        model.setOutTradeNo(outTradeNo);
        model.setTradeNo(null);
        alipayTradeQueryRequest.setBizModel(model);
        AlipayTradeQueryResponse alipay_response =alipayClient.execute(alipayTradeQueryRequest);
        logger.info("支付宝订单查询 response={}", JSONObject.toJSONString(alipay_response));
        if(alipay_response.isSuccess()){
            return alipay_response.getTradeStatus();
        } else {
        	logger.info("==================调用支付宝查询接口失败！");
        }
        return "TRADE_NOT_EXIST";
    }

    @Override
    public String aliPayReturnUrl(HttpServletRequest request) {
        return aliPayNotify(request);
    }

    @Override
    public String aliPayNotifyUrl(HttpServletRequest request) {
        return aliPayNotify(request);
    }

    /**
     * 功能描述 支付回调
     *
     * @param request
     * @return java.lang.String
     */
    public String aliPayNotify(HttpServletRequest request) {
        Map<String, String> params = Maps.newHashMap();
        try {
            Map requestParams = request.getParameterMap();
            for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
                String name = (String) iter.next();
                String[] values = (String[]) requestParams.get(name);
                String valueStr = "";
                for (int i = 0; i < values.length; i++) {
                    valueStr = (i == values.length - 1) ? valueStr + values[i]
                            : valueStr + values[i] + ",";
                }
                valueStr = new String(valueStr.getBytes(), "UTF-8");
                params.put(name, valueStr);
            }
            logger.info("支付宝回调，sign:{},trade_status:{},参数:{},out_trade_no:{},参数:{}", params.get("sign"),
                    params.get("trade_status"), params.get("out_trade_no"), params.toString());
            //调用SDK验证签名，验证是阿里回调，而不是其他恶意回调
            boolean flag = AlipaySignature.rsaCheckV1(params, ConstantUtil.alipay_public_key, "UTF-8", "RSA2");
            logger.info("flag的值是:" + flag);
            // 验证成功
            if (flag) { // 验证成功
                if (null == params.get("out_trade_no")) {
                    return "failue";
                }
                // 处理业务逻辑
                // String passbackParams = params.get("passback_params");//商户传入业务信息，具体值要和支付宝约定，应用于安全，营销等参数直传场景，格式为json格式
                String outTradeNo = params.get("out_trade_no");//商户订单号,64个字符以内、可包含字母、数字、下划线；需保证在商户端不重复
                logger.error("======支付订单号========" + outTradeNo);
                String totalAmount = params.get("buyer_pay_amount");//订单总金额，单位为元，精确到小数点后两位，取值范围[0.01,100000000]。
                logger.error("======订单总金额========" + totalAmount);

                if ("TRADE_SUCCESS".equals(params.get("trade_status"))) {
                    natatoriumOrderService.orderPaySuccess(outTradeNo);
                }
                return "success";
            }
            return "fail";

        } catch (Exception e) {
        	logger.info("订单回调异常:{}" + params.get("out_trade_no"));
            return "fail";
        }
    }


}
